package com.kay;

import com.kay.annotation.dao.UserAnnotationMapper;
import com.kay.dao.UserMapper;
import com.kay.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * @Description: MyBatis一级缓存、二级缓存存在验证、删除验证
 * @Author: Kay
 * @CreateDate: 2021/6/28$ 8:28$
 * @UpdateUser: Kay
 * @UpdateDate: 2021/6/28$ 8:28$
 */
public class CacheTest {
    private SqlSessionFactoryBuilder sqlSessionFactoryBuilder;
    private InputStream resourceAsStream;

    @Before
    public void before() throws IOException {
        resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();

    }

    /**
     * 测试一级缓存存在
     * 一级缓存是SqlSession级别的缓存  SqlSession间隔离 ；
     * 测试使用同一个 SqlSession对象，查看重复查询是否会多次发送SQL语句
     */
    @Test
    public void testLevelOneExist() {
        SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream);
        SqlSession sqlSession = sessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        System.out.println("--------------开始第一次查询---------------------");
        User user1 = userMapper.findById(1);
        System.out.println("------------第一次查询结束开始第二次查询-----------------------");
        User user2 = userMapper.findById(1);
        System.out.println("------------ 第二次查询结束-----------------------");
        System.out.println("两次查询出来的对象 user1 user2 是否相等 ： " + (user1 == user2));
    }


    /**
     * 测试一级缓存销毁触发条件
     * 同一个SqlSession的两次查询中间，增加一个增加、删除或修改操作并提交事务
     */
    @Test
    public void testLevelOneInvalid() {
        SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream);
        SqlSession sqlSession = sessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        System.out.println("--------------开始第一次查询---------------------");
        User user1 = userMapper.findById(1);
        System.out.println("------------第一次查询结束-----------------------");
        User user = new User();
        user.setId(3);
        user.setUsername("Kay");
        System.out.println("------------开始执行 insert、update、delete 操作 并提交事务-----------------------");
        userMapper.updateUsername(user);
        //userMapper.insertOne(user);
        //userMapper.deleteById(3);
        sqlSession.commit();
        System.out.println("------------开始第二次查询-----------------------");
        User user2 = userMapper.findById(1);
        System.out.println("------------ 第二次查询结束-----------------------");
        System.out.println("两次查询出来的对象 user1 user2 是否相等 ： " + (user1 == user2));
    }

    /**
     * 测试二级缓存是否存在
     */
    @Test
    public void testLevelTwoExist(){
        SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream);
        SqlSession sqlSession1 = sessionFactory.openSession();
        SqlSession sqlSession2 = sessionFactory.openSession();
        SqlSession sqlSession3 = sessionFactory.openSession(true);
        UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
        UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
        UserMapper userMapper3 = sqlSession3.getMapper(UserMapper.class);
        System.out.println("--------------执行SqlSession1创建的UserMapper1对象的查询---------------------");
        User user1 = userMapper1.findById(1);
        sqlSession1.close(); // 查询后关闭sqlSession1
        System.out.println("--------------执行SqlSession2创建的UserMapper2对象的查询---------------------");
        User user2 = userMapper2.findById(1);
        System.out.println("两次查询出来的对象 user1 user2 是否相等 ： " + (user1 == user2));
        sqlSession1.close();
    }

    /**
     * 测试二级缓存被删除
     */
    @Test
    public void testLevelTwoInvalid(){
        SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream);
        SqlSession sqlSession1 = sessionFactory.openSession();
        SqlSession sqlSession2 = sessionFactory.openSession();
        SqlSession sqlSession3 = sessionFactory.openSession(true);
        UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
        UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
        UserMapper userMapper3 = sqlSession3.getMapper(UserMapper.class);
        System.out.println("--------------执行SqlSession1创建的UserMapper1对象的查询---------------------");
        User user1 = userMapper1.findById(1);
        sqlSession1.close(); // 查询后关闭sqlSession1
        System.out.println("--------------执行SqlSession3创建的UserMapper3对象的增删改操作---------------------");
        User user = new User();
        user.setId(8);
        user.setUsername("sunshineKay");
        userMapper3.insertOne(user);// 插入后关闭sqlSession1
        sqlSession3.close();
        System.out.println("--------------执行SqlSession2创建的UserMapper2对象的查询---------------------");
        User user2 = userMapper2.findById(1);
        System.out.println("两次查询出来的对象 user1 user2 是否相等 ： " + (user1 == user2));
        sqlSession1.close();
    }

    /**
     * 测试二级缓存 当某个update设置 flushCache="false" 即更新后不刷新缓存
     */
    @Test
    public void testLevelTwoFlushCache(){
        SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream);
        SqlSession sqlSession1 = sessionFactory.openSession();
        SqlSession sqlSession2 = sessionFactory.openSession();
        SqlSession sqlSession3 = sessionFactory.openSession(true);
        UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
        UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
        UserMapper userMapper3 = sqlSession3.getMapper(UserMapper.class);
        System.out.println("--------------执行SqlSession1创建的UserMapper1对象的查询---------------------");
        User user1 = userMapper1.findById(1);
        System.out.println("id 为 1 的对象" + user1);
        sqlSession1.close(); // 查询后关闭sqlSession1
        System.out.println("--------------执行SqlSession3创建的UserMapper3对象的增删改操作---------------------");
        User user = new User();
        user.setId(1);
        user.setUsername("sunshineKay");
        userMapper3.updateUsername(user);// 插入后关闭sqlSession1
        sqlSession3.close();
        System.out.println("更新后id为1 的用户用户名 ： " + "sunshineKay");
        System.out.println("--------------执行SqlSession2创建的UserMapper2对象的查询---------------------");
        User user2 = userMapper2.findById(1);
        System.out.println("查询id 为 1 的对象 " + user2);
        System.out.println("两次查询出来的对象 user1 user2 是否相等 ： " + (user1 == user2));
        sqlSession1.close();
    }


    /**
     * 测试二级缓存是否存在 注解的方式
     */
    @Test
    public void testLevelTwoExistAnnotation(){
        SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream);
        SqlSession sqlSession1 = sessionFactory.openSession();
        SqlSession sqlSession2 = sessionFactory.openSession();
        SqlSession sqlSession3 = sessionFactory.openSession();
        UserAnnotationMapper userMapper1 = sqlSession1.getMapper(UserAnnotationMapper.class);
        UserAnnotationMapper userMapper2 = sqlSession2.getMapper(UserAnnotationMapper.class);
        UserAnnotationMapper userMapper3 = sqlSession3.getMapper(UserAnnotationMapper.class);
        System.out.println("--------------执行SqlSession1创建的UserMapper1对象的查询---------------------");
        User user1 = userMapper1.findOneById(1);
        sqlSession1.close();
        System.out.println("--------------执行SqlSession2创建的UserMapper2对象的查询---------------------");
        User user2 = userMapper2.findOneById(1);
        System.out.println("两次查询出来的对象 user1 user2 是否相等 ： " + (user1 == user2));
        sqlSession1.close();
    }

    /**
     * 测试二级缓存 当某个update设置 flushCache="false" 即更新后不刷新缓存
     */
    @Test
    public void testLevelTwoFlushCacheAnnotation(){
        SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream);
        SqlSession sqlSession1 = sessionFactory.openSession();
        SqlSession sqlSession2 = sessionFactory.openSession();
        SqlSession sqlSession3 = sessionFactory.openSession(true);
        UserAnnotationMapper userMapper1 = sqlSession1.getMapper(UserAnnotationMapper.class);
        UserAnnotationMapper userMapper2 = sqlSession2.getMapper(UserAnnotationMapper.class);
        UserAnnotationMapper userMapper3 = sqlSession3.getMapper(UserAnnotationMapper.class);
        System.out.println("--------------执行SqlSession1创建的UserMapper1对象的查询---------------------");
        User user1 = userMapper1.findOneById(1);
        System.out.println("id 为 1 的对象" + user1);
        sqlSession1.close(); // 查询后关闭sqlSession1
        System.out.println("--------------执行SqlSession3创建的UserMapper3对象的增删改操作---------------------");
        User user = new User();
        user.setId(1);
        String username= "MM";
        user.setUsername(username);
        userMapper3.updateUsername(user);// 插入后关闭sqlSession1
        sqlSession3.close();
        System.out.println("更新后id为1 的用户用户名 ： " + username);
        System.out.println("--------------执行SqlSession2创建的UserMapper2对象的查询---------------------");
        User user2 = userMapper2.findOneById(1);
        System.out.println("查询id 为 1 的对象 " + user2);
        System.out.println("两次查询出来的对象 user1 user2 是否相等 ： " + (user1 == user2));
        sqlSession1.close();
    }
}
